/*
 * @Author: xiaosihan 
 * @Date: 2022-09-20 23:06:00 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2023-05-09 23:47:31
 */


//mesh
import { BufferGeometry, Camera, Color, Group, Material, Clock, Mesh, DoubleSide, PlaneGeometry, Scene, ShaderChunk, ShaderMaterial, Vector2, WebGLRenderer } from "three";
import threeLoader from "three-base/threeLoader";
import { degToRad } from "three/src/math/MathUtils";
import floorMap1PNG from "./floorMap1.png";
import floorMap2PNG from "./floorMap2.png";
import floorMap3PNG from "./floorMap3.png";

// 地板
export default class Ground extends Mesh {
    constructor() {
        super();
    }

    renderOrder = -1;

    geometry = (() => {
        const geo = new PlaneGeometry(1, 1, 1, 1);
        geo.rotateX(degToRad(-90));
        return geo;
    })();

    // 设置尺寸
    setSize(width: number, height: number) {
        // this.scale.set(width, 1, height);
        // this.material.uniforms.size.value.set(width * 0.001, height * 0.001);
    }

    clock = new Clock();

    onBeforeRender = (renderer: WebGLRenderer, scene: Scene, camera: Camera, geometry: BufferGeometry, material: Material, group: Group) => {
        const elapsedTime = this.clock.getElapsedTime();
        this.material.uniforms.speed.value = elapsedTime * 0.1 % 0.6;
        this.material.uniforms.speed2.value = (elapsedTime * 0.1) % 0.6 - 0.1;
    };

    material = new ShaderMaterial({
        uniforms: {
            size: { value: new Vector2(10, 10) }, // 尺寸
            speed: { value: 0 }, // 扩散值0-1
            speed2: { value: 0 }, // 扩散值0-1
            speedColor: { value: new Color("#8D108E") }, // 格子扩散颜色
            lineColor: { value: new Color("#263C56") }, // 格子线的颜色
            map1: { value: threeLoader.getTexture(floorMap1PNG) }, // 贴图纹理
            map2: { value: threeLoader.getTexture(floorMap2PNG) }, // 贴图纹理
            map3: { value: threeLoader.getTexture(floorMap3PNG) }, // 贴图纹理
        },
        vertexShader: `
            ${ShaderChunk.common}
            ${ShaderChunk.logdepthbuf_pars_vertex}
            varying vec2 vUv;
            void main() {
                vUv = uv;
                gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
                ${ShaderChunk.logdepthbuf_vertex}
            }
        `,
        fragmentShader: `
            ${ShaderChunk.logdepthbuf_pars_fragment}
            uniform sampler2D map1;
            uniform sampler2D map2;
            uniform sampler2D map3;
            uniform vec2 size;
            uniform vec3 lineColor;
            uniform float speed;
            uniform float speed2;
            uniform vec3 speedColor;
            varying vec2 vUv;
            void main() {

                // 中心点
                vec2 center = vec2(0.5,0.5);

                vec4 map1Color = texture2D(map1, fract( vUv * size) );

                // 格子中心渐变颜色
                if(distance( vUv , center ) < speed){
                    map1Color = mix(map1Color, vec4(speedColor, 1.0),  clamp((1.0 - (distance(distance( vUv , center ), speed) * 8.0) ) * map1Color.a, 0.0, 1.0 ) );
                }

                vec4 map2Color = texture2D(map2, fract( vUv * size) );

                vec4 map3Color = texture2D(map3, fract( vUv * size) );

                // 正方形装饰中心渐变颜色
                if(distance( vUv , center ) < speed2){
                    map3Color = mix(map3Color, map3Color * 3.0,  clamp((1.0 - (distance(distance( vUv , center ), speed) * 4.0) ) * map3Color.a, 0.0, 1.0 ) );
                }

                vec4 mapColor = mix(map1Color, map2Color, map2Color.a);

                mapColor = mix(mapColor, map3Color, map3Color.a);

                //添加背景色
                mapColor = mix(mapColor, vec4(lineColor.rgb, 1.0 ), 1.0 - mapColor.a);

                // 设置透明度
                mapColor.a = 1.0 - (distance( vUv , center ) * 2.0);

                gl_FragColor = mapColor;

                ${ShaderChunk.logdepthbuf_fragment}
            }
        `,
        depthTest: true,
        depthWrite: true,
        transparent: true,
        side: DoubleSide
    });

}

